#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDesktopWidget>
#include <QDebug>
#include <QFileInfo>
#include <QIODevice>
#include <QStandardPaths>
#include <QFile>
#include <QDir>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    oldMousePos(0,0)
{
    ui->setupUi(this);
    //设置窗口位置
    this->readConfigInfo();
    this->setWindowFlags(Qt::FramelessWindowHint //去边框
                         |Qt::WindowStaysOnTopHint //最低层显示
                         |Qt::Tool //不在任务栏显示
                         );
    this->setAttribute(Qt::WA_TranslucentBackground, true);
    this->setSystemTray();
    process = new QProcess(this);
    timer = new QTimer(this);
    timer->connect(timer, SIGNAL(timeout()), this, SLOT(getInformation()));
    timer->start(1000);
}

void MainWindow::mousePressEvent(QMouseEvent *event){
    if(!isMousePressed && event->button() == Qt::LeftButton){
        isMousePressed = true;
        oldMousePos = event->globalPos() - this->pos();
        this->setCursor(Qt::ClosedHandCursor);
    }
}

void MainWindow::mouseMoveEvent(QMouseEvent *event){
    if(isMousePressed){
        this->move(event->globalPos() - oldMousePos);
        event->accept();
    }
}

void MainWindow::mouseReleaseEvent(QMouseEvent *event){
    if(isMousePressed && event->button() == Qt::LeftButton){
        int x = this->x();
        int y = this->y();
        if(this->pos().x() < 0){
            x = 0;
        }else if(QApplication::desktop()->width() - x < this->width()){
            x = QApplication::desktop()->width() - this->width();
        }
        if(this->pos().y() < 0) {
            y = 0;
        }else if(QApplication::desktop()->height()-y<this->height()){
            y = QApplication::desktop()->height()-this->height();
        }
        this->move(x,y);
        isMousePressed = false;
        setCursor(Qt::ArrowCursor);
        event->accept();
    }
}

void MainWindow::paintEvent(QPaintEvent *){

}

void MainWindow::closeEvent(QCloseEvent *event){
    this->writeConfigInfo();
    event->accept();
    QApplication::exit();
}

void MainWindow::onTrayMenuItemClick(HSystemTrayIcon::MenuItem item){
    switch(item){
    case HSystemTrayIcon::Monitor:
        this->openGnomeSystemMonitor();
        break;
    case HSystemTrayIcon::About:
        this->openAboutWindow();
        break;
    case HSystemTrayIcon::Exit:
        this->close();
        break;
    }
}

void MainWindow::writeConfigInfo(){
    QFile configFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).front() + "/.NetWatcher/config.ini");
    if(configFile.open(QIODevice::WriteOnly)){
        configFile.reset();
        QString posiMsg = "px=" + QString().setNum(this->pos().x()) + "," + "py=" + QString().setNum(this->pos().y());
        configFile.write(posiMsg.toUtf8());
        configFile.flush();
        configFile.close();
    }
}

void MainWindow::readConfigInfo(){
    QFile configFile(QStandardPaths::standardLocations(QStandardPaths::HomeLocation).front() + "/.NetWatcher/config.ini");
    //创建父目录
    QDir dir = QFileInfo(configFile).dir();
    dir.cd("../");
    dir.mkdir(".NetWatcher");
    //写入配置数据
    if(configFile.exists()){
        if(configFile.open(QIODevice::ReadOnly)){
            QString data = configFile.readAll();
            QStringList datas = data.split(",");
            if(!datas.isEmpty()){
                bool isOk = false;
                int x = datas.at(0).split("=").at(1).toInt(&isOk, 0);
                int y = datas.at(1).split("=").at(1).toInt(&isOk, 0);
                this->move(x, y);
                return;
            }
            configFile.close();
        }
    }else{
        this->move(QApplication::desktop()->width()-120,QApplication::desktop()->height()-80);
    }
}

void MainWindow::getInformation(){
    timer->stop();
    getNetInformation();
    getFreeMemoryInfo();
    timer->start(1000);
}

void MainWindow::getNetInformation(){
    uploadCount = 0;
    downloadCount = 0;
    process->start("ip -s link");
    if(process->waitForStarted(2000) && process->waitForFinished(1000)){
        QByteArray infoBytes = process->readAllStandardOutput();
        if(!infoBytes.isEmpty()){
            QString infoResult(infoBytes);
            //计算上传
            QRegularExpression regExpress("collsns[\\s\\S]+?\\d+");
            QRegularExpressionMatchIterator matcherIter = regExpress.globalMatch(infoResult);
            while(matcherIter.hasNext()){
                QString net = matcherIter.next().captured(0);
                net.remove(QRegularExpression("[\\s\\S]+ "));
                uploadCount += net.toInt();
            }
            qint64 tmp = uploadCount - oldUploadCount;
            if(oldUploadCount != 0)
                ui->lbUpload->setText("↑ " + getSizeInfo(tmp));
            oldUploadCount = uploadCount;
            //计算下载
            regExpress.setPattern("mcast[\\s\\S]+?\\d+");
            matcherIter = regExpress.globalMatch(infoResult);
            while(matcherIter.hasNext()){
                QString net = matcherIter.next().captured(0);
                net.remove(QRegularExpression("[\\s\\S]+ "));
                downloadCount += net.toLongLong();
            }
            tmp = downloadCount - oldDownloadCount;
            if(oldDownloadCount != 0)
                ui->lbDownload->setText("↓ " + getSizeInfo(tmp));
            oldDownloadCount = downloadCount;
        }
    }
}

void MainWindow::getFreeMemoryInfo(){
    process->start("free -m");
    if(process->waitForStarted(2000) && process->waitForFinished(1000)){
        QByteArray infoResult = process->readAllStandardOutput();
        if(!infoResult.isEmpty()){
            QRegularExpression regExpress("\\d+.+");
            QString value = regExpress.match(infoResult).captured(0);
            QStringList infoList = value.split(QRegExp(" +"));
            QString totalStr = infoList.at(0), availableStr = infoList.at(5);
            qint64 totalCount = totalStr.toLongLong(),
                    availableCount = availableStr.toLongLong();
            qint64 used = totalCount - availableCount;
            int usedPercent = qIntCast(used * 100.0 / totalCount);
            ui->pbMemory->setValue(usedPercent);
        }
    }
}

QString MainWindow::getSizeInfo(qint64 value){
    if(value >= 1024*1024){
        return QString().setNum(value/1024/1024) + "M/s";
    }else if(value >= 1024){
        return QString().setNum(value/1024)+"K/s";
    }else{
        return QString().setNum(value)+"B/s";
    }
}

void MainWindow::openGnomeSystemMonitor(){
    process->start("gnome-system-monitor");
    if(process->waitForStarted(2000) && process->waitForFinished(1000)){
        if(process->error() != QProcess::ProcessError::FailedToStart){
            //启动成功
        }
    }
}

void MainWindow::openAboutWindow(){
    aboutDialog = new AboutDialog();
    aboutDialog->show();
    aboutDialog->setFocus();
}

void MainWindow::setSystemTray(){
    trayIcon = new HSystemTrayIcon();
    QObject::connect(trayIcon, SIGNAL(onMenuItemClick(HSystemTrayIcon::MenuItem)), this, SLOT(onTrayMenuItemClick(HSystemTrayIcon::MenuItem)));
    trayIcon->show();
}

MainWindow::~MainWindow()
{
    delete ui;
}
